<?php


namespace app\meetyou\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;
use think\exception\PDOException;

/**
 * 众筹数据处理指令
 * Class AutoRun
 * @package app\meetyou\command
 */
class AutoRun extends Command {

    /**
     * 配置指令信息
     */
    protected function configure() {
        $this->setName('xtask:meetyou')->setDescription('处理众筹任务');
    }

    /**
     * 业务指令执行
     * @param Input $input
     * @param Output $output
     * @throws Exception
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws PDOException
     */
    protected function execute(Input $input, Output $output) {
        // 自动取消30分钟未支付的订单
        //$this->autoCancelOrder();
        // 清理一天前未支付的订单
        //$this->autoRemoveOrder();
        // 订单自动退款处理
        // $this->autoRefundOrder();
        // 提现自动打款处理
        // $this->autoTransfer();

        //匹配预约订单
        $this->autoReservationOrder();
    }

    /**
     * 自动匹配预约订单
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     * @throws PDOException
     */
    private function autoReservationOrder() {

        $time = time();
        //获取匹配时间段
        $date_range = sysconf('meetyou_reservation_range');
        if (!empty($date_range)) {
            $date_range = explode(' - ', $date_range);
            $_start_time = strtotime(date('Y-m-d ') . $date_range[0]);
            $_end_time = strtotime(date('Y-m-d ') . $date_range[1]);
            if ($_start_time > $_end_time) {
                $_start_time = $_end_time + ($_end_time = $_start_time) * 0;
            }
            if ($time < $_start_time && $time > $_end_time) {
                //$this->error('非预约时段，请等待！');
                return;
            }
        }

        $datetime = $this->getDatetime('meetyou_reservation_wait_time');

        //当天累计匹配单数
        $reservation_count = intval(sysconf('meetyou_transaction_range'));
        //每订单可匹配数量
        $meet_num = 2;

        //预约订单列表
        $reservation_order_list = db('meetyou_order')->alias('o')
            ->leftJoin('meetyou_member m', 'm.id=o.mid')
            ->where([['o.status', 'eq', '0'], ['o.pay_orderid', 'eq', '0'], ['o.pay_status', 'eq', '0'], ['o.create_at', '<', $datetime]])
            ->where('m.status', '<>', 0)
            ->order(['o.reservation_order' => 'desc', 'o.create_at' => 'asc'])
            ->limit($reservation_count)
            ->select();

        $count = 0;
        if (!empty($reservation_order_list)) {
            foreach ($reservation_order_list as $order) {
                //查找匹配订单 transaction
                $transaction_order = db('meetyou_order')->alias('o')
                    ->leftJoin('meetyou_member m', 'm.id=o.mid')
                    ->where([['o.status', 'eq', '3'], ['o.meet_num', '<', $meet_num], ['m.status', '<>', '0'],['o.mid','<>',$order['mid']]])
                    ->order(['o.meet_num' => 'asc', 'o.transaction_order' => 'desc', 'o.create_at' => 'asc'])
                    ->find();
                if (!empty($transaction_order)) {
                    $count++;
                    //更新预约订单
                    db('meetyou_order')->update([
                        'pay_orderid' => $transaction_order['id'],
                        'status'      => 1,
                        'update_at'   => $time,
                        'id'          => $order['id']

                    ]);

                    //更新匹配订单
                    db('meetyou_order')->update([
                        'meet_num'  => intval($transaction_order['meet_num']) + 1,
                        'update_at' => $time,
                        'id'        => $transaction_order['id']
                    ]);
                }
            }
        }

        if ($count > 0) {
            $this->output->info("共计自动匹配了{$count}笔订单！");
        } else {
            $this->output->comment('没有匹配到订单记录！');
        }
        $this->output->newLine();
    }

    /**
     * 获取配置时间
     * @param string $code
     * @return string
     * @throws Exception
     * @throws PDOException
     */
    private function getDatetime($code) {
        $minutes = intval(sysconf($code) * 60);
        return date('Y-m-d H:i:s', strtotime("-{$minutes} minutes"));
    }

}
